#
# Copyright (c) 2009-2011 NITLab, University of Thessaly, CERTH, Greece
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# = reservations_check.rb
#
# == Description
#
# This file checks the scheduler database for the reservations that end or begin
# at the next time slot. After that it disables and/or enables the proper nodes.
# This file should by executed automatically by crontab as root.
#

#-------------------------------------------------------------#
#---- The functionalities of this file were enhanced by ------#
#------- LABORA - Federal University of Goiás (UFG). ---------#
#-------------------------------------------------------------#

require 'mysql'

# Get current time and transform it based on the time slots we use (half an hour time slots).
# Note that we execute the script at minutes 28 and 58.
time = Time.new
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
if (time.min < 30)
  previous_slot_end_time = time.strftime("%Y-%m-%d %H:00:00")
else
  previous_slot_end_time = time.strftime("%Y-%m-%d %H:30:00")
end

# Connect to scheduler database.
con = Mysql.new("localhost", "omfi", "omfi", "scheduler")

#-------------------------------------------------------------#
#----- Permit and Deny SSH conections - by LABORA - UFG ------#
#-------------------------------------------------------------#

`iptables -D OUTPUT -o eth1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j SSH`
`iptables -F SSH`
`iptables -X SSH`

`iptables -N SSH`
`iptables -A OUTPUT -o eth1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j SSH`

query = "SELECT username, control_ip FROM scheduler.reservation AS r, " +
        "inventory.nodes AS n WHERE r.node_id=n.id " +
        "AND r.begin_time<'#{current_time}' AND r.end_time>'#{current_time}'"
rs = con.query(query)
rs.each_hash do |r|
  `iptables -A SSH -d #{r["control_ip"]} -m owner --uid-owner #{r["username"]} -j ACCEPT`
end

`iptables -A SSH -m owner --uid-owner root -j ACCEPT`
`iptables -A SSH -j DROP`

#-------------------------------------------------------------#
#-------------------------------------------------------------#
#-------------------------------------------------------------#

#-------------------------------------------------------------#
#-- Reboot nodes after reservation period - by LABORA - UFG --#
#-------------------------------------------------------------#
query = "SELECT control_ip FROM inventory.nodes AS n, " +
        "scheduler.reservation AS r WHERE n.id = r.node_id " +
        "AND r.end_time = '#{previous_slot_end_time}' " +
        "AND (control_ip, username) NOT IN " +
        "(SELECT control_ip, username FROM inventory.nodes AS n, " +
        "scheduler.reservation AS r WHERE n.id = r.node_id " +
        "AND r.begin_time<'#{current_time}' AND r.end_time>'#{current_time}');"
rs = con.query(query)
rs.each_hash do |n|
  `ssh root@#{n["control_ip"]} reboot`
end
#-------------------------------------------------------------#
#-------------------------------------------------------------#
#-------------------------------------------------------------#



#------------ Disable Nodes -------------------
#query = "select reservation.username, node_list.y from reservation join node_list on reservation.node_id=node_list.id where reservation.begin_time='#{next_slot}'"
#rs = con.query(query)
#rs.each_hash do |h|
  #cmd = `disable_node #{h["username"]} #{h["y"]}`
  #cmd = `omf_create_psnode-5.3 nitlab.inf.uth.gr rmnode /OMF/#{h["username"]}/resources/omf.nitos.#{h["nane"]}`
  #When CM cards get ready, power off the node (future work).
#end

#------------ Enable Nodes --------------------
#query = "select reservation.username, node_list.y from reservation join node_list on reservation.node_id=node_list.id where reservation.begin_time='#{next_slot}'"
#rs = con.query(query)
#rs.each_hash do |h|
  #cmd = `enable_node #{h["username"]} #{h["y"]}`
  #cmd = `omf_create_psnode-5.3 nitlab.inf.uth.gr sliceadd #{h["username"]} omf.nitos.#{h["nane"]}`
#end

con.close
